from fastapi import APIRouter, Body, Path, Query, Depends
from backend.db.neo4j_driver import neo4j_driver
from backend.utils.logger import logger
from backend.utils.response_filter import filter_sensitive_fields
from backend.schemas.line import LineCreate, LineUpdate, LineDetail, LineWorkbenchUpdate
from backend.auth.auth import get_current_user
from datetime import datetime
from typing import List, Optional
from backend.utils.consts import SERVER_INTERNAL_ERROR_MSG, LINE_NOT_FOUND_MSG
from backend.cypher_defs.cypher_line import (
    MATCH_LINE_BY_ID,
    GET_LINE_LIST,
    GET_LINE_DETAIL_WORKBENCHES,
    CREATE_LINE,
    UPDATE_LINE,
    DELETE_LINE,
    DELETE_LINE_WORKBENCH_REL,
    CREATE_LINE_WORKBENCH_REL,
    GET_LINE_WORKBENCHES,
    CHECK_LINE_EXISTS
)
from backend.utils.model_utils import fill_create_update_fields, fill_update_fields

router = APIRouter(prefix="/api/lines", tags=["line"])

@router.get(
    "/",
    response_model=dict,
    summary="获取产线列表",
    description="支持按产线名称或编号模糊查询，返回所有产线信息。"
)
async def get_line_list(keyword: Optional[str] = Query(None, description="产线名称或编号")):
    try:
        cypher = GET_LINE_LIST.format(where=" WHERE l.lineName CONTAINS $keyword OR l.lineId CONTAINS $keyword" if keyword else "")
        params = {}
        if keyword:
            params["keyword"] = keyword
        result = neo4j_driver.query(cypher, params)
        data = [r["l"] for r in result]
        data = filter_sensitive_fields(data)
        return {"code": 0, "msg": "success", "data": data}
    except Exception as e:
        logger.error(f"Error in get_line_list: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.get(
    "/{lineId}",
    response_model=dict,
    summary="获取产线详情",
    description="根据产线ID获取产线的详细信息。"
)
async def get_line_detail(lineId: str = Path(...)):
    try:
        cypher = MATCH_LINE_BY_ID
        result = neo4j_driver.query(cypher, {"lineId": lineId})
        if not result:
            return {"code": 1013, "msg": LINE_NOT_FOUND_MSG, "data": None}
        line = result[0]["l"]
        # 查询产线下工台
        cypher = GET_LINE_DETAIL_WORKBENCHES
        ws = neo4j_driver.query(cypher, {"lineId": lineId})
        line["workbenches"] = [x["w"] for x in ws]
        return {"code": 0, "msg": "success", "data": line}
    except Exception as e:
        logger.error(f"Error in get_line_detail: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.post(
    "/",
    response_model=dict,
    summary="创建产线",
    description="创建新的产线节点，产线ID不可重复。"
)
async def create_line(
    body: LineCreate,
    current_user: str = Depends(get_current_user)
):
    try:
        cypher = CHECK_LINE_EXISTS
        if body.lineId and neo4j_driver.query(cypher, {"lineId": body.lineId}):
            return {"code": 1011, "msg": "产线ID已存在", "data": None}
        params = body.dict(exclude={"createdBy", "createdAt", "updatedBy", "updatedAt"})
        params = fill_create_update_fields(params, current_user)
        cypher = CREATE_LINE
        result = neo4j_driver.query(cypher, params)
        data = result[0]["l"] if result else None
        return {"code": 0, "msg": "success", "data": data}
    except Exception as e:
        logger.error(f"Error in create_line: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.put(
    "/{lineId}",
    response_model=dict,
    summary="更新产线信息",
    description="根据产线ID更新产线基本信息。"
)
async def update_line(
    lineId: str = Path(...),
    body: LineUpdate = Body(...),
    current_user: str = Depends(get_current_user)
):
    try:
        cypher = CHECK_LINE_EXISTS
        if not neo4j_driver.query(cypher, {"lineId": lineId}):
            return {"code": 1013, "msg": LINE_NOT_FOUND_MSG, "data": None}
        set_clauses = []
        params = {"lineId": lineId}
        for k, v in body.dict(exclude_unset=True).items():
            if k in ["lineName", "status", "describe"]:
                set_clauses.append(f"l.{k} = ${{k}}")
                params[k] = v
        params = fill_update_fields(params, current_user)
        set_clauses.append("l.updatedBy = $updatedBy")
        set_clauses.append("l.updatedAt = $updatedAt")
        if set_clauses:
            cypher = UPDATE_LINE.replace('{set_clauses}', ', '.join(set_clauses))
            result = neo4j_driver.query(cypher, params)
            data = result[0]["l"] if result else None
        else:
            data = None
        return {"code": 0, "msg": "success", "data": data}
    except Exception as e:
        logger.error(f"Error in update_line: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.delete(
    "/{lineId}",
    response_model=dict,
    summary="删除产线",
    description="根据产线ID删除产线节点及其所有关联关系。"
)
async def delete_line(lineId: str = Path(...)):
    try:
        cypher = DELETE_LINE
        neo4j_driver.query(cypher, {"lineId": lineId})
        return {"code": 0, "msg": "success", "data": None}
    except Exception as e:
        logger.error(f"Error in delete_line: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.put("/{lineId}/workbenches", response_model=dict)
async def update_line_workbenches(lineId: str = Path(...), body: LineWorkbenchUpdate = Body(...)):
    try:
        # 先删除原有关系
        cypher = DELETE_LINE_WORKBENCH_REL
        neo4j_driver.query(cypher, {"lineId": lineId})
        # 再建立新关系
        for bench in body.benches:
            benchId = bench["benchId"]
            cypher = CREATE_LINE_WORKBENCH_REL
            neo4j_driver.query(cypher, {"lineId": lineId, "benchId": benchId})
        return {"code": 0, "msg": "success"}
    except Exception as e:
        logger.error(f"Error in update_line_workbenches: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.get("/{lineId}/workbenches", response_model=dict)
async def get_line_workbenches(lineId: str = Path(...)):
    try:
        cypher = "MATCH (l:Line {lineId: $lineId})-[:LINE_CONTAINS]->(w:WorkBench) RETURN w"
        result = neo4j_driver.query(cypher, {"lineId": lineId})
        data = [r["w"] for r in result]
        return {"code": 0, "msg": "success", "data": data}
    except Exception as e:
        logger.error(f"Error in get_line_workbenches: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None} 